home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / CBuilder / Setup / BCB / data.z / numbrw.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-09  |  16.1 KB  |  608 lines

  1. #ifndef __STD_RW_NUMBRW_CC__
  2. #define __STD_RW_NUMBRW_CC__
  3. #pragma option push -b -a4 -Vx- -Ve- -w-inl -w-aus -w-sig
  4.  
  5. /****************************************************************************
  6.  *
  7.  * rw/numbrw.cc - Internal classes for numeric formatting and parsing.
  8.  *
  9.  * $Id: numbrw.cc,v 1.23 1996/10/22 05:12:47 delaney Exp $
  10.  *
  11.  ***************************************************************************
  12.  *
  13.  * (c) Copyright 1994, 1995 Rogue Wave Software, Inc.
  14.  * ALL RIGHTS RESERVED *
  15.  * The software and information contained herein are proprietary to, and
  16.  * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
  17.  * intends to preserve as trade secrets such software and information.
  18.  * This software is furnished pursuant to a written license agreement and
  19.  * may be used, copied, transmitted, and stored only in accordance with
  20.  * the terms of such license and with the inclusion of the above copyright
  21.  * notice.  This software and information or any other copies thereof may
  22.  * not be provided or otherwise made available to any other person.
  23.  *
  24.  * Notwithstanding any other lease or license that may pertain to, or
  25.  * accompany the delivery of, this computer software and information, the
  26.  * rights of the Government regarding its use, reproduction and disclosure
  27.  * are as set forth in Section 52.227-19 of the FARS Computer
  28.  * Software-Restricted Rights clause.
  29.  *
  30.  * Use, duplication, or disclosure by the Government is subject to
  31.  * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
  32.  * Technical Data and Computer Software clause at DFARS 252.227-7013.
  33.  * Contractor/Manufacturer is Rogue Wave Software, Inc.,
  34.  * P.O. Box 2328, Corvallis, Oregon 97339.
  35.  *
  36.  * This computer software and information is distributed with "restricted
  37.  * rights."  Use, duplication or disclosure is subject to restrictions as
  38.  * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
  39.  * Computer Software-Restricted Rights (April 1985)."  If the Clause at
  40.  * 18-52.227-74 "Rights in Data General" is specified in the contract,
  41.  * then the "Alternate III" clause applies.
  42.  *
  43.  ***************************************************************************/
  44.  
  45.  
  46. #ifndef _RWSTD_NO_NAMESPACE
  47. namespace __rwstd {
  48. #endif
  49.  
  50. // ------------------------------------------------
  51. // Template timepunct_data<charT> member templates.
  52. // ------------------------------------------------
  53.  
  54. template <class charT>
  55. timepunct_data<charT>::timepunct_data
  56.     (const timepunct_init<charT> &init)
  57. {
  58.   int i;
  59.   for (i=0; i<7; i++) {
  60.     dn_[i][0]=init.dn_[i][0];
  61.     dn_[i][1]=init.dn_[i][1];
  62.   }
  63.   for (i=0; i<12; i++) {
  64.     mn_[i][0]=init.mn_[i][0];
  65.     mn_[i][1]=init.mn_[i][1];
  66.   }
  67.   ampm_[0]=init.ampm_[0];
  68.   ampm_[1]=init.ampm_[1];
  69.   bad_=init.bad_;
  70.   for (i=0; i<100; i++)
  71.     ord_[i]=init.ord_[i];
  72.   for (i=0; i<sizeof pat_/sizeof pat_[0]; i++)
  73.     pat_[i]=init.pat_[i];
  74. }
  75.  
  76. template <class charT>
  77. void timepunct_data<charT>::rw_init (void) {
  78.   int i;
  79.   for (i=0; i<7; i++) {
  80.     dn_defs_[i][0].s=dn_[i][0].c_str();
  81.     dn_defs_[i][0].v=i;
  82.     dn_defs_[i][1].s=dn_[i][1].c_str();
  83.     dn_defs_[i][1].v=i;
  84.   }
  85.  
  86.   for (i=0; i<12; i++) {
  87.     mn_defs_[i][0].s=mn_[i][0].c_str();
  88.     mn_defs_[i][0].v=i;
  89.     mn_defs_[i][1].s=mn_[i][1].c_str();
  90.     mn_defs_[i][1].v=i;
  91.   }
  92.  
  93.   dn_map_.num_defs_=7*2;
  94.   dn_map_.defs_=&(dn_defs_[0][0]);
  95.   mn_map_.num_defs_=12*2;
  96.   mn_map_.defs_=&(mn_defs_[0][0]);
  97. }
  98.  
  99.  
  100. // -----------------------------------------------
  101. // Facet rwstd::timepunct<charT> member templates.
  102. // -----------------------------------------------
  103.  
  104. #ifndef _RWSTD_NO_NAMESPACE
  105. } namespace __rwstd { // Leave std, enter __rwstd
  106. #endif
  107.  
  108. template <class charT>
  109. locale::id timepunct<charT>::id;
  110.  
  111. template <class charT>
  112. void timepunct<charT>::rw_init () {
  113.   int n;
  114.   for (n=0; n<7; n++) {
  115.     this->dn_[n][false]=do_dayname(n,false);
  116.     this->dn_[n][true]=do_dayname(n,true);
  117.   }
  118.   for (n=0; n<12; n++) {
  119.     this->mn_[n][false]=do_monthname(n,false);
  120.     this->mn_[n][true]=do_monthname(n,true);
  121.   }
  122.   for (n=0; n<100; n++)
  123.     this->ord_[n]=do_ordinal(n);
  124.  
  125.   timepunct_impl<charT>::rw_init();
  126. }
  127.  
  128. template <class charT>
  129. _TYPENAME timepunct<charT>::string_type
  130. timepunct<charT>::do_dayname (int day, bool abbr) const {
  131.   return this->dn_[day][abbr];
  132. }
  133.  
  134. template <class charT>
  135. _TYPENAME timepunct<charT>::string_type
  136. timepunct<charT>::do_monthname (int mon, bool abbr) const {
  137.   return this->mn_[mon][abbr];
  138. }
  139.  
  140. template <class charT>
  141. _TYPENAME timepunct<charT>::string_type
  142. timepunct<charT>::do_ordinal (int number) const {
  143.   return (number<0 || number>99) ? this->bad_ : this->ord_[number];
  144. }
  145.  
  146.  
  147.  
  148. // -----------------------------------------------
  149. // Template digit_handler_base_1 member templates.
  150. // -----------------------------------------------
  151.  
  152. template <class charT>
  153. digit_handler_base_1<charT>::
  154. digit_handler_base_1 (const locale &loc):
  155. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  156.     ctyp(use_facet<ctype<charT> >(loc)),
  157.     dmap(digit_map<charT>::get_digit_map(ctyp)),
  158.     punct(use_facet<numpunct<charT> >(loc))
  159. #else
  160.     ctyp(use_facet(loc,(ctype<charT>*)0)),
  161.     dmap(digit_map<charT>::get_digit_map(ctyp)),
  162.     punct(use_facet(loc,(numpunct<charT>*)0))
  163. #endif
  164. { }
  165.  
  166. template <class charT>
  167. digit_handler_base_1<charT>::
  168. digit_handler_base_1
  169.     (const locale &loc, const punct_data<charT> &pun):
  170. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  171.     ctyp(use_facet<ctype<charT> >(loc)),
  172.     dmap(digit_map<charT>::get_digit_map(ctyp)),
  173. #else
  174.     ctyp(use_facet(loc,(ctype<charT>*)0)),
  175.     dmap(digit_map<charT>::get_digit_map(ctyp)),
  176. #endif
  177.     punct(pun)
  178. { }
  179.  
  180. // ----------------------------------------------
  181. // Template digit_reader_base_1 member templates.
  182. // ----------------------------------------------
  183.  
  184. template <class charT>
  185. digit_reader_base_1<charT>::
  186. digit_reader_base_1 (const locale &loc):
  187.     digit_handler_base_1<charT>(loc)
  188. { }
  189.  
  190. template <class charT>
  191. digit_reader_base_1<charT>::
  192. digit_reader_base_1 (const locale &loc,
  193.     const punct_data<charT> &mp):
  194.     digit_handler_base_1<charT>(loc,mp)
  195. { }
  196.  
  197. // ---------------------------------------
  198. // Template digit_reader member templates.
  199. // ---------------------------------------
  200.  
  201. template <class charT,class InputIterator>
  202. digit_reader<charT,InputIterator>::
  203. digit_reader(InputIterator& i,InputIterator& e,ios_base &b):
  204.     digit_reader_base_1<charT>(b.getloc()),
  205.     io(b), in(i), end(e)
  206. { }
  207.  
  208. template <class charT,class InputIterator>
  209. digit_reader<charT,InputIterator>::
  210. digit_reader(InputIterator& i,InputIterator& e,ios_base &b,
  211.     const punct_data<charT> &mp):
  212.     digit_reader_base_1<charT>(b.getloc(),mp),
  213.     io(b), in(i), end(e)
  214. { }
  215.  
  216. template <class charT,class InputIterator>
  217. char* digit_reader<charT,InputIterator>::
  218.     get_digit_string (char *dpos)
  219. {
  220.   char *eod=dpos;
  221.   int i;
  222.  
  223.   while (!at_end() && (i=this->dmap.eval(*in))>=0 && i<this->radix) {
  224.     if (eod==this->digits+sizeof this->digits)
  225.       this->error|=this->too_many_digits;
  226.     else
  227.       *eod++=(char) i;
  228.     ++in;
  229.   }
  230.  
  231.   return eod;
  232. }
  233.  
  234. template <class charT,class InputIterator>
  235. char* digit_reader<charT,InputIterator>::
  236.     get_int_digits (void)
  237. {
  238.   charT c;
  239.   char *eod=this->digits;
  240.   const charT* ctype_punct=this->dmap.get_punct();
  241.  
  242.   if (!at_end() && this->is_signed)
  243.     // If a sign is present, set negative if it's a minus sign.
  244.     do {
  245.       if ((c=*in)==ctype_punct[this->minus])
  246.         this->negative=true;
  247.       else if (c!=ctype_punct[this->plus])
  248.         break;
  249.       // Eat white space after the sign.  Standard seems to mandate this
  250.       // regardless of whether ios_base::skipws is set.
  251.       do
  252.         ++in;
  253.       while (!at_end() && this->ctyp.is(ctype_base::space,*in));
  254.       this->advanced=true;
  255.     } while (0);
  256.  
  257.   if (!this->radix) {
  258.     switch (io.flags() & ios_base::basefield) {
  259.      case ios_base::dec:
  260.       this->radix=10;
  261.       break;
  262.      case ios_base::hex:
  263.       this->radix=16;
  264.       break;
  265.      case ios_base::oct:
  266.       this->radix=8;
  267.       break;
  268.      default:
  269.       // No radix was forced by the ios_base flags, so poke around for a radix
  270.       // specifier on the front of the input value.
  271.       this->radix=10;
  272.       if (!at_end() && *in==ctype_punct[this->zero]) {
  273.         this->radix=8;
  274.         ++in;
  275.         *eod++=0;
  276.         this->advanced=true;
  277.         if (!at_end() &&
  278.             ((c=*in)==ctype_punct[this->x] || c==ctype_punct[this->X]))
  279.         {
  280.           this->radix=16;
  281.           ++in;
  282.           eod--; // Leading 0 was not a digit after all.
  283.         }
  284.       }
  285.     }
  286.   }
  287.  
  288.   grouping=this->get_grouping();
  289.   if (!*grouping)
  290.     eod=get_digit_string(eod);
  291.   else {
  292.     gpos=groups;
  293.     thousands_sep=get_thousands_sep();
  294.     eod=get_digit_groups(eod);
  295.     if (!this->error && --gpos>groups) {
  296.       // Digit grouping is optional, but if present it must be right.
  297.       const char *gdef=grouping;
  298.       do {
  299.         if (*gdef!=*gpos && *gdef!=CHAR_MAX)
  300.           break;
  301.         else
  302.           if (gdef[1])
  303.             gdef++;
  304.       } while (--gpos>groups);
  305.  
  306.       if (gpos>groups || *gpos>*gdef)
  307.         this->error|=this->bad_grouping;
  308.     }
  309.   }
  310.  
  311.   if (eod>this->digits)
  312.     this->advanced=true;
  313.   return eod;
  314. }
  315.  
  316. template <class charT,class InputIterator>
  317. char* digit_reader<charT,InputIterator>::
  318.     get_float_digits (void)
  319. {
  320.   charT c;
  321.   this->radix=10;
  322.   char *eod=get_int_digits();
  323.  
  324.   const charT *ctyp_punct=this->dmap.get_punct();
  325.  
  326.   this->frac_beg=eod;
  327.   if (!this->error && !at_end() && *in==get_decimal_point()) {
  328.     in++;
  329.     eod=get_digit_string(eod);
  330.   }
  331.  
  332.   if (eod==this->digits)
  333.     this->error|=this->no_digits;
  334.  
  335.   this->exp_beg=eod;
  336.   this->exp_negative=false;
  337.   if (!this->error && !at_end() &&
  338.       ((c=*in)==ctyp_punct[this->e] || c==ctyp_punct[this->E]))
  339.   {
  340.     in++;
  341.     if (at_end())
  342.       this->error|=this->bad_exponent;
  343.     else {
  344.       if ((c=*in)==ctyp_punct[this->plus])
  345.         in++;
  346.       else if (c==ctyp_punct[this->minus]) {
  347.         this->exp_negative=true;
  348.         in++;
  349.       }
  350.  
  351.       int save_radix=this->radix;
  352.       this->radix=10;
  353.       eod=get_digit_string(eod);
  354.       this->radix=save_radix;
  355.       if (eod==this->exp_beg)
  356.         this->error|=this->bad_exponent;
  357.     }
  358.   }
  359.  
  360.   return eod;
  361. }
  362.  
  363. template <class charT,class InputIterator>
  364. char *digit_reader<charT,InputIterator>::
  365.     get_pointer_digits (void)
  366. {
  367.   this->radix=16;
  368.   char *eod=get_int_digits();
  369.   return eod;
  370. }
  371.  
  372. template <class charT,class InputIterator>
  373. char* digit_reader<charT,InputIterator>::
  374.     get_digit_groups (char *dpos)
  375. {
  376.   char *eod=get_digit_string(dpos);
  377.  
  378.   if (gpos==groups+sizeof groups)
  379.     this->error|=this->too_many_groups;
  380.   else {
  381.     int i=eod-dpos;
  382.     if (i >= CHAR_MAX)
  383.       this->error|=this->group_too_long;
  384.     else {
  385.       *gpos++=i;
  386.       if (i!=0 && !at_end() && *in==thousands_sep) {
  387.         ++in;
  388.         eod=get_digit_groups(eod);
  389.       }
  390.     }
  391.   }
  392.  
  393.   return eod;
  394. }
  395.  
  396. template <class charT,class InputIterator>
  397. int digit_reader<charT,InputIterator>::
  398.     get_keyword (const keyword_map<charT> &mapit)
  399. {
  400.   const keyword_def<charT> *canp=mapit.defs_;
  401.   const keyword_def<charT> *endp=mapit.defs_+mapit.num_defs_;
  402.   keyword_def<charT> cans[40],*ansp=cans;
  403.  
  404.   charT c;
  405.   const charT *p;
  406.   int result;
  407.  
  408.   while (1) {
  409.     if (at_end()) {
  410.       for ( ; canp<endp; canp++)
  411.         if (!*canp->s)
  412.           return canp->v;
  413.       return -1;
  414.     }
  415.     c=*in;
  416.     result=-1;
  417.     for ( ; canp<endp; canp++) {
  418.       p=canp->s;
  419.       if (c==*p) {
  420.         ansp->s=++p;
  421.         ansp->v=canp->v;
  422.         ansp++;
  423.       } else if (*p==0)
  424.         result=ansp->v; // abbreviation
  425.     }
  426.  
  427.     if (ansp==cans)
  428.       return result;
  429.     in++;
  430.     if (ansp==cans+1) {
  431.       for (p=cans[0].s; *p; p++) {
  432.         if (at_end() || *in!=*p)
  433.           return -1;
  434.         in++;
  435.       }
  436.       return cans[0].v;
  437.     }
  438.  
  439.     endp=ansp;
  440.     ansp=cans;
  441.     canp=cans;
  442.   }
  443. }
  444.  
  445. // ----------------------------------------------
  446. // Template digit_writer_base_1 member templates.
  447. // ----------------------------------------------
  448.  
  449. template <class charT>
  450. digit_writer_base_1<charT>::
  451. digit_writer_base_1(ios_base &b,const locale &loc) 
  452.  : digit_writer_base(b), digit_handler_base_1<charT>(loc)
  453. { }
  454.  
  455. template <class charT>
  456. digit_writer_base_1<charT>::
  457. digit_writer_base_1(ios_base &b,const punct_data<charT> &mp)
  458.  : digit_writer_base(b),digit_handler_base_1<charT>(b.getloc(),mp)
  459. {
  460.   flags&=~(ios_base::floatfield|ios_base::showpos);
  461.   flags|=ios_base::fixed;
  462.   radix=10;
  463.   precision=0;
  464. }
  465.  
  466. // ---------------------------------------
  467. // Template digit_writer member templates.
  468. // ---------------------------------------
  469.  
  470. template <class charT,class OutputIterator>
  471. digit_writer<charT,OutputIterator>::
  472. digit_writer (OutputIterator &o, ios_base &b)
  473.  : digit_writer_base_1<charT>(b,b.getloc()), out(o) 
  474. { }
  475.  
  476. template <class charT,class OutputIterator>
  477. digit_writer<charT,OutputIterator>::
  478. digit_writer (OutputIterator &o, ios_base &b,
  479.     const punct_data<charT> &mp)
  480.  : digit_writer_base_1<charT>(b,mp), out(o) 
  481. { }
  482.  
  483. template <class charT, class OutputIterator>
  484. void digit_writer<charT,OutputIterator>::put_digits (charT fill)
  485. {
  486.   char *p=this->start;
  487.   bool has_sign=false,has_point=false;
  488.   if (p<this->end && (*p==' ' || *p=='-' || *p=='+'))
  489.     has_sign=true;
  490.  
  491.   // Locate the end of the integral digits.
  492.   char *dec;
  493.   if (!this->fractional)
  494.     dec=this->end;
  495.   else {
  496.     dec=this->start;
  497.     if (has_sign) dec++;
  498.     for ( ; dec<this->end; dec++)
  499.       if (*dec<'0' || *dec>'9') {
  500.         if (*dec!='e' && *dec!='E')
  501.           has_point=true;
  502.         break;
  503.       }
  504.   }
  505.  
  506.   // Calculate the number and pattern of separators needed if any.
  507.   charT separator;
  508.   int unGrouped=dec-this->start;
  509.   if (has_sign)
  510.     unGrouped--;
  511.   if (this->radix==10 && this->separable) {
  512.     unGrouped=calc_groups(unGrouped,this->get_grouping());
  513.     if (this->num_groups)
  514.       separator=get_thousands_sep();
  515.   }
  516.  
  517.   // Compute the number of fill charT-s needed, and where they should be put.
  518.   int leftFill=0,internalFill=0,rightFill=0;
  519.   if (this->width>0) {
  520.     int w=this->width - (this->end - this->start) - this->num_groups;
  521.     this->width=0;
  522.     if (w>0) {
  523.       switch (this->adjust) {
  524.        case digit_writer_base::left:
  525.         rightFill=w;
  526.         break;
  527.        case digit_writer_base::internal:
  528.         internalFill=w;
  529.         break;
  530.        default:
  531.         leftFill=w;
  532.       }
  533.     }
  534.   }
  535.  
  536.   // Widen the sign + digits + exponent string.
  537. //charT wide_digits[sizeof digit_writer_base::buffer];
  538.   charT wide_digits[400];
  539.   this->ctyp.widen(this->start,this->end,wide_digits);
  540.  
  541.   // Write the widened string with fill and decorations to output.
  542.   charT *digit_pos=wide_digits;
  543.   while (leftFill--)
  544.     *out++=fill;
  545.   if (has_sign)
  546.     *out++=*digit_pos++;    // the widened sign
  547.   while (internalFill--)
  548.     *out++=fill;
  549.   while (unGrouped--)
  550.     *out++=*digit_pos++;
  551.   while (this->num_groups--) {
  552.     *out++=separator;
  553.     while (this->group[0]--)
  554.       *out++=*digit_pos++;
  555.     this->group++;
  556.   }
  557.  
  558.   if (has_point) {
  559.     *out++=get_decimal_point();
  560.     digit_pos++;
  561.   }
  562.  
  563.   unGrouped=this->end-dec;
  564.   if (has_point)
  565.     unGrouped--;
  566.   while (unGrouped-->0)
  567.     *out++=*digit_pos++;
  568.  
  569.   while (rightFill--)
  570.     *out++=fill;
  571. }
  572.  
  573. template <class charT, class OutputIterator>
  574. void digit_writer<charT,OutputIterator>::
  575.     put_keyword (const string_type &k, charT fill)
  576. {
  577.   int leftFill=0,rightFill=0;
  578.   int n=this->width-k.length();
  579.   if (n>0) {
  580.     switch (this->adjust) {
  581.      case digit_writer_base::left:
  582.       rightFill=n;
  583.       break;
  584.      case digit_writer_base::internal:
  585.      default:
  586.       leftFill=n;
  587.     }
  588.     if (leftFill)
  589.       do *out++=fill;
  590.       while (--leftFill);
  591.   }
  592.  
  593.   const charT *p=k.c_str(),*end=p+k.length();
  594.   while (p<end)
  595.     *out++=*p++;
  596.  
  597.   if (rightFill)
  598.     do *out++=fill;
  599.     while (--rightFill);
  600. }
  601.  
  602. #ifndef _RWSTD_NO_NAMESPACE
  603. } // namespace __rwstd
  604. #endif
  605.  
  606. #pragma option pop
  607. #endif // __STD_RW_NUMBRW_CC__
  608.